package com.ckx.config.web;

import com.ckx.base.BizException;
import com.ckx.base.CommonResult;
import com.ckx.constant.ExceptionExceptionEnum;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.MessageSource;
import org.springframework.http.ResponseEntity;
import org.springframework.util.Assert;
import org.springframework.validation.BindException;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import java.util.Locale;

import static java.util.stream.Collectors.joining;
import static org.springframework.http.HttpStatus.BAD_REQUEST;

@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {

    @Resource
    private MessageSource messageSource;

    @ExceptionHandler(BindException.class)
    @ResponseStatus(code = BAD_REQUEST)
    public ResponseEntity<CommonResult<Object>> bindExceptionHandler(BindException e) {
        log.warn(e.getMessage(), e);
        final String message =
                e.getBindingResult().getFieldErrors().stream()
                        .map(FieldError::getDefaultMessage)
                        .limit(1)
                        .collect(joining(", "));
        ExceptionExceptionEnum illegalArgument = ExceptionExceptionEnum.ILLEGAL_ARGUMENT;
        return ResponseEntity.ok(CommonResult.fail(illegalArgument.code(), message));
    }

    @ExceptionHandler(value = BizException.class)
    public ResponseEntity<CommonResult<Object>> handeException(BizException e) {
        Locale locale = getLocale();

        int code = e.getCode();
        Object[] args = e.getArgs();
        String msg = messageSource.getMessage(code + ".message", args, locale);
        return ResponseEntity.ok(CommonResult.fail(code, msg));
    }


    @ExceptionHandler(value = Exception.class)
    public ResponseEntity<CommonResult<Object>> handeException(Exception e) {
        log.error("系统异常0", e);
        Locale locale = getLocale();

        ExceptionExceptionEnum systemError = ExceptionExceptionEnum.SYSTEM_ERROR;
        int code = systemError.code();
        String msg = messageSource.getMessage(code + ".message", null, locale);

        return ResponseEntity.ok(CommonResult.fail(code, msg));
    }

    private static Locale getLocale() {
        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
        Assert.notNull(requestAttributes, "没有request");
        HttpServletRequest request = ((ServletRequestAttributes) requestAttributes).getRequest();
        return request.getLocale();
    }
}
